﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows.Input;
using ExCombatAssist.Settings;
using ff14bot;
using ff14bot.Helpers;
using ff14bot.Managers;
using ff14bot.Navigation;
using ff14bot.AClasses;
using ff14bot.Behavior;
using TreeSharp;
using System.Windows.Forms;
using Newtonsoft.Json;
using System.IO;
using System.Configuration;
using System.Globalization;

namespace ExCombatAssist
{
    public class ExCombatAssist : BotBase
   {
       public static ExCombatAssistSets settings = ExCombatAssistSets.instance;
       private ExCombatAssistSettings _form;
       private Composite _root;

       #region Necessary Stuff
        public override string Name
        {
            get { return "Ex Combat Assist"; }
        }
        public override bool IsAutonomous
        {
            get { return false; }
        }

        public override bool WantButton
        {
            get
            {
                return true;
            }
        }
        public override void OnButtonPress()
        {
            if (_form == null || _form.IsDisposed || _form.Disposing)
                _form = new ExCombatAssistSettings();

            _form.ShowDialog();  
        }

        public override void Start()
        {
            ExCombatAssistSets.instance.IsPaused = false;
            settings.UseEchoNotification = false;
            Navigator.PlayerMover = new NullMover();
            HotkeyManager.Register("Pause Key", settings.PauseKeyChoice, settings.ModKeyChoice, hk => { settings.IsPaused = !settings.IsPaused; Logging.Write(settings.IsPaused ? "ExCombatAssist Paused!" : "ExCombatAssist Resumed!"); });
        }

        [DllImport("user32.dll")]
        public static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

  
        public override bool RequiresProfile
        {
            get { return false; }
        }
        public override void Stop()
        {
            HotkeyManager.Unregister("Pause Key");
        } 
        public override PulseFlags PulseFlags
        {
            get { return PulseFlags.All; }
        }

#endregion
       public override Composite Root
        {
            get
            {
                return _root ?? (_root =
                    new PrioritySelector(
                        new Decorator(ret => settings.IsPaused, new ActionAlwaysSucceed()),
                        SelectLockMethod(
                            new Decorator(ret =>
                            {
                                if (!Core.Player.InCombat)
                                    return false;

                                if (!Core.Player.HasTarget)
                                    return false;

                                if (settings.DontDoActionList.Contains(Core.Player.CurrentTarget.Name))
                                    return false;

                                return true;
                            }, new PrioritySelector(
                                RoutineManager.Current.CombatBuffBehavior,
                                RoutineManager.Current.HealBehavior,
                                RoutineManager.Current.CombatBehavior
                                )),
                            new Decorator(ret =>
                            {
                                if (!Core.Player.InCombat && Core.Player.HasTarget)
                                    return false;

                                return true;
                            }, new PrioritySelector(
                                RoutineManager.Current.HealBehavior)),
                            new Decorator(ret =>
                            {
                                if (Core.Player.InCombat)
                                    return false;

                                return true;
                            }, new PrioritySelector(
                                RoutineManager.Current.HealBehavior)),
                            RoutineManager.Current.HealBehavior
                            )));
            }
        }
       #region Frame Lock from nomnom! Thank you.

        private static Composite SelectLockMethod(params Composite[] children)
        {
            return settings.UseFrameLock ? new LockSelector(children) : new PrioritySelector(children);
        }
   }
        public class LockSelector : PrioritySelector
        {
            public LockSelector(params Composite[] children)
                : base(children)
            {
            }

            public override RunStatus Tick(object context)
            {
                using (Core.Memory.AcquireFrame())
                {
                    return base.Tick(context);
                }
            }
        }
#endregion
}

namespace ExCombatAssist.Settings
{
    public class ExCombatAssistSets : JsonSettings
    {
        [JsonIgnore]
        private static ExCombatAssistSets _instance;
        public static ExCombatAssistSets instance { get { return _instance ?? (_instance = new ExCombatAssistSets("ExCombatAssistSets")); } }
        public ExCombatAssistSets(string filename) : base(Path.Combine(CharacterSettingsDirectory, "ExCombatAssist.json")) { }

        #region TypeConverter
        public class CsvConverter : TypeConverter
        {
            // Overrides the ConvertTo method of TypeConverter.
            public override object ConvertTo(ITypeDescriptorContext context,
               CultureInfo culture, object value, Type destinationType)
            {
                List<String> v = value as List<String>;
                if (destinationType == typeof(string))
                {
                    return String.Join(",", v.ToArray());
                }
                return base.ConvertTo(context, culture, value, destinationType);
            }
        }

        public sealed class StringListConverter : StringConverter
        {

            public static string[] value;
            public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
            {
                return true;
            }

            public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
            {
                return true;
            }

            public override TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
            {
                return new StandardValuesCollection(value);
            }
        }
        #endregion

        private BindingList<String> _dontdoactionlist;

        [Setting]
        [Browsable(false)]
        public BindingList<string> DontDoActionList
        {
            get
            {
                if (_dontdoactionlist == null)
                    _dontdoactionlist = new BindingList<String>();
                return _dontdoactionlist;
            }
        }

        [Setting, DefaultValue(Keys.X)]
        public Keys PauseKeyChoice { get; set; }

        [Setting, DefaultValue(ModifierKeys.Shift)]
        public ModifierKeys ModKeyChoice { get; set; }

        [Setting, DefaultValue(false)]
        public bool PluginPulsing { get; set; }

        [Setting, DefaultValue(false)]
        
        public bool IsPaused { get; set; }


        [Setting, DefaultValue(false)]
        public bool UseFrameLock { get; set; }

        [Setting, DefaultValue(false)]
        public bool UseEchoNotification { get; set; }
    }
    

}
